home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / science / nrlibe32.zip / NRLIB32.C < prev    next >
Text File  |  1994-11-23  |  79KB  |  2,175 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*            ROUTINES FOR MULTIPLE NEURAL NETWORKS MANAGEMENT                */
  4. /*       (routines for ERROR BACK PROPAGATION training are included)          */
  5. /*                                                                            */
  6. /*                      Version  3.2 (32 bits/16 bits)                        */
  7. /*                       Copyright by Daniele Denaro                          */
  8. /******************************************************************************/
  9.  
  10. /* Switch depending on hardware and compilators */
  11. /* B16 (DOS ) B32 (DOS 32 bits ,UNIX etc.) */
  12.  
  13. # define B16                      /* modify depending on hardware or compil.  */
  14.  
  15. /******************************************************************************/
  16. /*                                                                            */
  17. /*  Abstract of library   functionalities :                                   */
  18. /*     - Nets create   in memory ; one or more nets different too             */
  19. /*     - Save and load all nets on/from file                                  */
  20. /*     - Net compute (input propagate)                                        */
  21. /*     - Net training with  EBP (Error Back Propagation)                      */
  22. /*                                                                            */
  23. /*  Each net can have any number of layers .                                  */
  24. /*                                                                            */
  25. /*  Each layer can have any number of nodes .                                 */
  26. /*                                                                            */
  27. /*  Each node can have any number of links with others nodes .                */
  28. /*                                                                            */
  29. /*  Nodes are automatically numbered with progressive number in net .         */
  30. /*                                                                            */
  31. /*  One can choose a different activation function for each node. There are   */
  32. /*  ten types of activation function : 6 defined and 3 for user definition.   */
  33. /*  For each node it's also possible to define another function, named action,*/
  34. /*  which is called after the activation function.                            */
  35. /*                                                                            */
  36. /*                                                                            */
  37. /*  Range of principals values                                                */
  38. /*                                                                            */
  39. /*  Maximum values:                                                           */
  40. /*                                                                            */
  41. /*     - Maximum net number     : 1000 (in this release)                      */
  42. /*     - Maximum layer number   : 99  (in  a  net)                            */
  43. /*     - Maximum node number    : 7FFFFFFF(hex) (in a net)                    */
  44. /*                                                                            */
  45. /*  Minimum values:                                                           */
  46. /*                                                                            */
  47. /*     - First net              : 1                                           */
  48. /*     - First layer in a net   : 0 (input layer)                             */
  49. /*     - First node  in a net   : 1                                           */
  50. /*                                                                            */
  51. /*                                                                            */
  52. /******************************************************************************/
  53.  
  54. /******************************************************************************/
  55. /*                                                                            */
  56. /*   Neural network architecture:                                             */
  57. /*                                                                            */
  58. /*                                                                            */
  59. /*   Network m                                                                */
  60. /*             /|\                                                            */
  61. /*   Layer n    |                                                             */
  62. /*       ---------------            Each layer is automatically linked with   */
  63. /*             /|\                  next layer and all nodes of layer i are   */
  64. /*              |                   linked with all nodes of layer i+1.       */
  65. /*    ----------------------                                                  */
  66. /*              :                   Network creation :                        */
  67. /*              :                   - by function <createnet> ;               */
  68. /*              :                     we however need to define the structure */
  69. /*   Layer 1    :                     of all nets list,first by <createstruct>*/
  70. /*    ----------------------          This structure can be defined if we know*/
  71. /*             /|\                    the total number of nets and the maximum*/
  72. /*   Layer 0    |                     layer number for each net.              */
  73. /*     --------------------         - it's also possible to define the struct.*/
  74. /*             /|\                    of net list and all nets in the same    */
  75. /*              |                     time,by the function <creteallnet> , if */
  76. /*                                    the nets have the same size.            */
  77. /*                                  - we can save or load all nets by function*/
  78. /*                                    <savenet> or <loadnet> .                */
  79. /*   Layer i                          That  functions are relative to all nets*/
  80. /*             /|\                    but the total number of nets can be     */
  81. /*   Node k     |                     reduced by the function <wmnet>.        */
  82. /*    +-------------------+           Nets loading doesn't need structure of  */
  83. /*    |       status      |           nets list and overwrite it if exist.    */
  84. /*    |--activ. function--|.......                                            */
  85. /*    |        inp        |                                                   */
  86. /*    +-------------------+                                                   */
  87. /*             /|\                  Other warning on creation functions:      */
  88. /*              |                   for default , weights are initialised with*/
  89. /*                                  a random value between -.4 and +.4, and   */
  90. /*                                  bias for all nodes are 0.                 */
  91. /*                                                                            */
  92. /*                                                                            */
  93. /*                                                                            */
  94. /* Warning:                                                                   */
  95. /*    although the library is optimized for simple forward networks, it's     */
  96. /*    possible create and manage very complex network using functions for     */
  97. /*    single node or single layer.                                            */
  98. /*    Version 4 was implemented for optimize manage for complex network       */
  99. /*    (ie. complex layers links, contest memory, recursive link etc.)         */
  100. /******************************************************************************/
  101.  
  102. /******************************************************************************/
  103. /*                                                                            */
  104. /*   Net elaboration and training                                             */
  105. /*                                                                            */
  106. /*   Forward propagation:                                                     */
  107. /*                                                                            */
  108. /*   Basic function is <propagate> ; this function forward propagate net from */
  109. /*   layer A to layer  B.                                                     */
  110. /*   For each node of a layer the activation function is calculated on input  */
  111. /*   value and result (status of activation) is added at input of pointed node*/
  112. /*   after scaling by weight factor.                                          */
  113. /*                                                                            */
  114. /*   The function <compute> is more general; she call previous function       */
  115. /*   between first and last layer. We have to supply input values and after   */
  116. /*   we can obtain the output values.                                         */
  117. /*                                                                            */
  118. /*   <produce> is the most general function    ; she need file of input values*/
  119. /*   and produce a file of ouput values.                                      */
  120. /*   Input file format : n-ple of input values (corresp. at n inp. of layer 0)*/
  121. /*                                                                            */
  122. /*                                                                            */
  123. /*   Backward training :                                                      */
  124. /*                                                                            */
  125. /*   Basic function is <backprop> ; this function apply the EBP rule from     */
  126. /*   layer B to layer A .                                                     */
  127. /*   For each node of a layer the error value is calculated on basis of error */
  128. /*   at next layer and at the same time weigts  are corrected     .           */
  129. /*   At end , error at layer A is loss.                                       */
  130. /*   We can backpropagate only error without weigts correction by function    */
  131. /*   <backproperr> instead of previous function; but in this case we must use */
  132. /*   the function <cancerr> after, because buffers for forward and backward   */
  133. /*   are partially coincident .                                               */
  134. /*   For default bias is not modified , but it's possible do it by function   */
  135. /*   <param> . By this function it's possible also modify   the learning and  */
  136. /*   moment coefficients (for default 0.8 and 0.5) .                          */
  137. /*                                                                            */
  138. /*   Function <learn> is more general ; she call previous function for all    */
  139. /*   layer of net.                                                            */
  140. /*                                                                            */
  141. /*   <train> is the most general function ; she need the trainer file  and    */
  142. /*   produce average quadratic error. She reed the trainer file for ep times  */
  143. /*   (where ep = 1 for default) .                                             */
  144. /*   Trainer file format : n-pla (input values)   m-pla (exact out values)    */
  145. /*   (where n = nodes at layer 0  , m= nodes at last layer )                  */
  146. /*                                                                            */
  147. /*                                                                            */
  148. /*                                                                            */
  149. /******************************************************************************/
  150.  
  151.  
  152. # ifdef B16
  153. # define far far
  154. # define LONG long
  155. # define CLOCK_PS 18.2
  156. # define ALLOCA farcalloc
  157. # define LIBERA farfree
  158. # include <dos.h>
  159. # include <alloc.h>
  160. # endif
  161.  
  162. # ifdef B32
  163. # define far
  164. # define LONG  int
  165. # define ALLOCA calloc
  166. # define LIBERA free
  167. # define CLOCK_PS 100
  168. # endif
  169.  
  170. # include <stdio.h>
  171. # include <math.h>
  172. # include <stdlib.h>
  173.  
  174. /******************************************************************************/
  175.  
  176. # define MAX_RAND 0x7FFF
  177.  
  178. # define NULLO 0
  179.  
  180.  
  181. # define NOMEM    1
  182. # define NOFILEI  2
  183. # define NOFILEO  3
  184. # define NODIM    4
  185. # define NONODO   5
  186. # define TOOCOLL  6
  187. # define NOLIV    7
  188. # define TOOLIV   8
  189. # define NOMEMV   9
  190. # define NOFILEES 10
  191. # define ERRESE   11
  192. # define NOTRETE  12
  193. # define NOTLIV   13
  194. # define NONUMR   14
  195. # define TOONET   15
  196. # define NOSTRUCT 16
  197. # define CREARETE 17
  198.  
  199. /*****************************************************************************/
  200.  
  201. static char fileinp[255]="nnetsinp.dat";  /* file di caricamento rete     */
  202. static char fileout[255]="nnetsout.dat";  /* file di scaricamento rete    */
  203. static char fileese[255]="nettrain.dat";  /* file di esempi               */
  204.  
  205. static int      nep=1;                    /* numero epoche di addestram.  */
  206. static float    minerr=0;                 /* errore minimo di convergenza */
  207. static float    epsl= 0.8;                /* cost. apprendimento          */
  208. static float    alfa= 0.5;                /* coeff. di momento            */
  209. static float    randa=-0.4;               /* estremo inf. gen. rand. pesi */
  210. static float    randb=0.4;                /* estremo sup. gen. rand. pesi */
  211. static int      numr= 1;                  /* num. della rete in consideraz.*/
  212. static int      flgbias=0;      /* no*/   /* flag per la correzione del bias*/
  213. static int      flgdeb=2;                 /* flag visualizz. (def=mass.)  */
  214.  
  215. static int      flgrete=0;                /* flag di rete definita*/
  216. static int      flgstrr=0;                /* flag di struttura reti definita*/
  217. /*****************************************************************************/
  218.  
  219.  
  220. /*****************************************************************************/
  221. /*  Struttura delle reti in memoria :                                         */
  222. /*                                                                            */
  223. /*               +-------+           rete 1                    rete n         */
  224. /*               | rete 1|-------------|      nodi      :          +--------+ */
  225. /*    livelli  |-|       |             |---> +--------+ :  +-----+ | nodo 1 | */
  226. /*    +-----+<-| |-------|        link       | nodo 1 | :  |-----| |        | */
  227. /*    |-----|    |       |       +------+<---|        | :  |-----| |--------| */
  228. /*    |-----|    |       |       |------|    |--------| :  |-----| :        : */
  229. /*    |-----|    :       :       |------|    :        : :  |-----| |--------| */
  230. /*    :     :    :       :       |------|    :        : :  :     : | nodo n | */
  231. /*    :     :    |       |       :      :    |--------| :  |-----| |        | */
  232. /*    |-----|    |-------|       |------|  |-| nodo n | :  |-----| +--------+ */
  233. /*    |-----|    | rete n|--|    |------|<-| |        | :  +-----+            */
  234. /*    |-----|<---|       |  |    |------|    +--------+ :                     */
  235. /*    |-----|    +-------+  |    +------+               :            ^        */
  236. /*    |-----|               |                           :            |        */
  237. /*    +-----+               |----------------------------------------|        */
  238. /*                                                                            */
  239. /******************************************************************************/
  240.  
  241.  
  242.                       /* vettore di dimens. = totr+1 */
  243. static struct rete                        /* struttura di supporto reti    */
  244. {
  245.   LONG d1;                                /* numero massimo di nodo */
  246.   LONG d2;                                /* numero totale di collegamenti */
  247.   struct nodo far *nodo;                  /* puntatore alla struttura nodi */
  248.   struct coll far *inicoll;               /* puntatore alla struttura colleg.*/
  249.   int  maxliv;                            /* livello massimo */
  250.   struct livello far *liv;                /* puntatore alla struttura livelli*/
  251. };
  252.                       /* vettore di dimens. = totl */
  253. static struct livello                     /* struttura livelli */
  254. {
  255.   LONG sn;                                /* minimo nodo del livello */
  256.   LONG en;                                /* massimo nodo del livello */
  257. };
  258.  
  259.                 /* vettore di dimens. = d1 (piu' prec. d1+1)*/
  260. static struct  nodo             /* struttura del nodo */
  261. {
  262.   float bias;                   /* soglia */
  263.   float dbias;                  /* variaz. della soglia del passo prec.*/
  264.   float inp;                    /* input del ciclo precedente (util. da funz)*/
  265.   float stato;                  /* stato ; aggiornato da funz */
  266.   int  far (*funz)();           /* funzione di trasferimento */
  267.   int  far (*azione)();         /* eventuale azione */
  268.   LONG  ncoll;                  /* numero dei collegamenti in uscita */
  269.   struct coll far *coll;        /* puntatore al vettore collegamenti */
  270. }  ;
  271.                 /* vettore di dimens. = d2 */
  272. static struct coll              /* struttura collegamenti */
  273. {
  274.   float peso;                   /* peso del collegamento */
  275.   float dp;                     /* variazione del peso nel passo prec.*/
  276.   LONG nodo;                    /* nodo puntato */
  277. }  ;
  278.  
  279.  
  280.  
  281. static struct rete    far *r;      /* puntatore al primo elemento di rete*/
  282. static struct livello far *iniliv; /* puntatore al primo elemento di livello*/
  283.  
  284. static int  totr;                /* massimo numero di rete */
  285. static LONG totl;                /* numero totale di livelli */
  286.  
  287. static char copyright[]="C.o.py.ri.ght b.y D.a.n.i.e.l.e D.e.n.a.r.o";
  288.  
  289. /*************************  FUNCTIONS DECLARATIONS **************************/
  290.  
  291. int   loadnet(char *fileinp);
  292.             /* Load all networks from file <fileinp> to memory  */
  293.             /* In the same time create structure for nets list  */
  294.             /* Par. inp.: fileinp (file name)                   */
  295.             /*            if fileinp="" default = nnetsinp.dat  */
  296.  
  297. int   savenet(char *fileout);
  298.             /* Save all networks from memory to file <fileout>  */
  299.             /* Par. inp.: fileout (file name)                   */
  300.             /*            if fileout="" default = nnetsout.dat  */
  301.  
  302. int   createallnet(int tn,int nlay,LONG vn[],char vf[][10],char va[][10]);
  303.             /* Create <tn> same nets in memory and the structure*/
  304.             /* that describe them.                              */
  305.             /* Links between layers are wholes and the weight   */
  306.             /* are initialized with a value between ra=-.4 and  */
  307.             /* rb=+.4 (see function <param> for ra and rb def.) */
  308.             /* Par. inp.:tn   (total nets)                      */
  309.             /*           nliv (max layer)                       */
  310.             /*           vn[] (array of tot. nodes for each lay)*/
  311.             /*           vf[] (array of a.fun name for each lay)*/
  312.             /*           va[] (array of act. name for each lay) */
  313.  
  314. int   createstruct(int tn,int vlay[]);
  315.             /* Create the structure that describe list of all   */
  316.             /* networks. We need create this before create      */
  317.             /* single net.                                      */
  318.             /* It is possible to define nets with different lay */
  319.             /* Par. inp.: tn     (total nets )                  */
  320.             /*            vlay[] (array of max lay for each net)*/
  321.  
  322. int   createnet(int net,LONG vn[],char vf[][10],char va[][10]);
  323.             /* Create single net .                              */
  324.             /* (structure of nets list must already exist)      */
  325.             /* We can define total nodes , activation function  */
  326.             /* and action for each layer of net.                */
  327.             /* Par. inp.: net   (net number or id)              */
  328.             /*            vn[]  (array of total nodes for lay)  */
  329.             /*            vf[]  (array of a.fun. name for lay)  */
  330.             /*            va[]  (array of act. name for lay)    */
  331.  
  332. int   ininet(int net);
  333.             /* Overwrite weigts with random number between <ra> */
  334.             /* and <rb> (see function <param> )                 */
  335.             /* Par. inp.: net   (net number)                    */
  336.  
  337. int   copynet(int nta,int ntb);
  338.             /* Copy net A to net B .                            */
  339.             /* Warning: because the function sequencialy copy   */
  340.             /* characteristics from    A nodes to B nodes, if   */
  341.             /* A e B nets are not the same the result can be    */
  342.             /* unpredictible .                                  */
  343.             /* Par. inp.: nta   (net A )                        */
  344.             /*            ntb   (net B )                        */
  345.  
  346. int   cancnets();
  347.             /* Dealloc memory for all nets and structure        */
  348.  
  349.  
  350. int   param(char *name, char *val);
  351.             /* Modify global parameters     .                   */
  352.             /* Parameters names :                               */
  353.             /* ne (epochs number for   EBP;           def. 1)   */
  354.             /* er (min q. error for stop EBP;         def. 0)   */
  355.             /* ep (learning coefficient for EBP;      def. 0.8) */
  356.             /* mo (momentum coefficient for EBP;      def. 0.5) */
  357.             /* ra (weigts random gener. start value ; def.-0.4) */
  358.             /* rb (weigts random gener. end value   ; def. 0.4) */
  359.             /* fb (flag bias training; 1=yes        ; def. 0)   */
  360.             /* fd (flag verbose    ;                  def. 1)   */
  361.             /* Par. inp.: name  (param. name)                   */
  362.             /*            val   (ascii value)                   */
  363.  
  364. int   produce(int net,char *finpdat, char *foutdat);
  365.             /* The most general function for net forward        */
  366.             /* computation.                                     */
  367.             /* Read input values(of layer 0) from file <finpdat>*/
  368.             /* and write output values(of last layer) on file   */
  369.             /* <foutdat>.                                       */
  370.             /* (function <produce> call function <compute>)     */
  371.             /* Par. inp.: net     (net number)                  */
  372.             /*            finpdat (input file name)             */
  373.             /*                     if *finpdat = "" def.= stdinp*/
  374.             /*            foutdat (output file name)            */
  375.             /*                     if *foutdat = "" def.= stdout*/
  376.  
  377.   float compute(int net,float vinp[],float vout[],float vdat[]);
  378.             /* Forward computation for a net.                   */
  379.             /* Read input values (of layer 0) from the array    */
  380.             /* <vinp>  ,  write output values (of last layer)   */
  381.             /* on the array <vout> and compare <vout> with      */
  382.             /* <vdat> values (expected values) , at last, over- */
  383.             /* write <vdat> with error (for next EBP phase).    */
  384.             /* Warning: vinp[1] is input for first node of lay 0*/
  385.             /* and vout[1] is status of first node of last layer*/
  386.             /* Return value is the average quadratic error for  */
  387.             /* output nodes .                                   */
  388.             /* (function <compute> call function <propagate>)   */
  389.             /* Par. inp.: net    (net number)                   */
  390.             /*            vinp[] (array of input data)          */
  391.             /*            vdat[] (array of out expected  )      */
  392.             /* Par. out.: vout[] (array of out data)            */
  393.             /*            vdat[] (array of out errors)          */
  394.             /* Return   : average q. error                      */
  395.  
  396.     int   propagate(int net,int laya,int layb);
  397.             /* Propagate input from layer A to layer B          */
  398.             /* Par. inp.: net  (net number)                     */
  399.             /*            laya (layer numer)                    */
  400.             /*            layb (layer number)                   */
  401.  
  402. float train(int net,char *filetrain);
  403.             /* The most general function for EBP training.      */
  404.             /* Read couple of values for input nodes and output */
  405.             /* expected values from file <*filetrain>, and      */
  406.             /* modify weigts applying EBP rule .                */
  407.             /* The function has 2 phases : first call <compute> */
  408.             /* to propagate input and after call <learn> to     */
  409.             /* apply EBP rule.                                  */
  410.             /* Training is repeated for <ne> cycles (see <param>*/
  411.             /* (function <train> call <compute> and <learn> )   */
  412.             /* Par. inp.: net  (net number)                     */
  413.             /*            filetrain (file trainer name)         */
  414.             /*                if *filetrain="" def.=nettrain.dat*/
  415.             /* Return   : total averege q. error                */
  416.  
  417.   int   learn(int net,float verr[]);
  418.             /* Function for net EBP training.                   */
  419.             /* Read error  values (out computed - out expected) */
  420.             /* from array <verr> and apply EBP rule at whole   */
  421.             /* net,backpropagating error and modifying weigts . */
  422.             /* Warning: verr[1] is error of first node of last  */
  423.             /* layer.                                           */
  424.             /* (function <learn> call function <backprop>)      */
  425.             /* Par. inp.: net    (net number)                   */
  426.             /*            verr[] (errors array)                 */
  427.  
  428.     int   backprop(int net,int laya,int layb);
  429.             /* Backpropagate errors and modify weigts from layer*/
  430.             /* B to layer A .                                   */
  431.             /* We must write errors buffers of layer B before   */
  432.             /* to call this function (see function <werrl>)     */
  433.             /* Par. inp.: net  (net number)                     */
  434.             /*            laya (layer number  )                 */
  435.             /*            layb (layer number    )               */
  436.  
  437. int  backproperr(int net,int laya,int layb);
  438.             /* Backpropagate errors but don't modify weigts .   */
  439.             /* Warning: this function don't clear errors buffers*/
  440.             /* Par. inp.: net  (net number)                     */
  441.             /*            laya (layer number)                   */
  442.             /*            layb (layer number)                   */
  443.  
  444. int  cancerr(int net,int laya,int layb);
  445.             /* Clear errors buffers.                            */
  446.             /* We must call this function after <backproperr>   */
  447.             /* because errors buffers are partialy utilized by  */
  448.             /* forward propagation.                             */
  449.             /* Par. inp.: net  (net number)                     */
  450.             /*            laya (layer number)                   */
  451.             /*            layb (layer number)                   */
  452.  
  453.  
  454. /******************* Functions for single node  or layer *********************/
  455.  
  456. /* In this functions <net> is net number and <nn> is node number            */
  457.  
  458. /* Warn.: we can dinamicaly modify max layer number or total node link,but  */
  459. /*        only reducing the initial values.                                 */
  460.  
  461. /* Net functions                                                            */
  462.  
  463. int   rmnet(int *totnet);
  464.             /* Read max net number   (total nets)               */
  465.  
  466. int   wmnet(int totnet);
  467.             /* Reduce total nets                                */
  468.  
  469. int   rmlay(int net,int *mlay);
  470.             /* Read max layer number of a net                   */
  471.  
  472. int   totnn(int net, LONG *tnode);
  473.             /* Read total node number of a net                  */
  474.  
  475. int   wmlay(int net,int mlay);
  476.             /* Reduce max layer number of a net                 */
  477.  
  478. int   rlay(int net,int nlay,LONG *sn,LONG *en);
  479.             /* Read start and end node number of a layer        */
  480.  
  481. /* Next 12 functions are dedicated to layer nodes management in groups.     */
  482. /* Therefore I/O buffer is an array ; first element is alwais [1] (not [0]).*/
  483. /* If the array dimension is < than we need, return value is -1 , but       */
  484. /* element are readed or writed as possible.                                */
  485. /* (<nlay..> is the layer number,  <dim> is the array dimension of buffer)  */
  486.  
  487. int   rstatl(int net,int nlay,float stat[],int dim);
  488.             /* Read nodes status of layer <nlay> to array <stat>*/
  489.  
  490. int   wstatl(int net,int nlay,float stat[],int dim);
  491.             /* Modify nodes status of layer <nlay> from <stat>  */
  492.  
  493. int   rinpl(int net,int nlay,float inp[],int dim);
  494.             /* Read nodes inp of layer <nlay> to array <inp>    */
  495.  
  496. int   winpl(int net,int nlay,float inp[],int dim);
  497.             /* Modify nodes inp of layer <nlay> from <inp> val. */
  498.  
  499. int   rerrl(int net,int nlay,float err[],int dim);
  500.             /* Read backprop. error at layer <nlay> to <err>    */
  501.  
  502. int   werrl(int net,int nlay,float err[],int dim);
  503.             /* Modify error buffer at layer <nlay> from <err>   */
  504.  
  505. int   rbiasl(int net,int nlay,float bias[],int dim);
  506.             /* Read nodes bias of layer <nlay> to array <bias>  */
  507.  
  508. int   wbiasl(int net,int nlay,float bias[],int dim);
  509.             /* Modify nodes bias of layer <nlay> from <bias>    */
  510.  
  511. int   rwgtl(int net,LONG nn,int nlayp,float wgt[],int dim);
  512.             /* Read weigts of node <nn> linked with lay <nlayp> */
  513.  
  514. int   wwgtl(int net,LONG nn,int nlayp,float wgt[],int dim);
  515.             /* Modify weigts of node <nn> linked with <nlayp>   */
  516.  
  517. int   rwgtil(int net,LONG npp,int nlaya,float wgt[],int dim);
  518.             /* Read weigts of links at node <npp> from <nlaya>  */
  519.  
  520. int   wwgtil(int net,LONG npp,int nlaya,float wgt[],int dim);
  521.             /* Modify weigts of links at node <npp> from <nlaya>*/
  522.  
  523. /* Single node functions                                                    */
  524.  
  525. int   rstat(int net,LONG nn,float *stat);
  526.             /* Read node activation status                      */
  527.  
  528. int   rbias(int net,LONG nn,float *bias);
  529.             /* Read node bias                                   */
  530.  
  531. int   rinp(int net,LONG nn,float *inp);
  532.             /* Read node input                                  */
  533.  
  534. int   rerr(int net,LONG nn,float *err);
  535.             /* Read node error in EBP phase                     */
  536.  
  537. int   rfun(int net,LONG nn,char fun[10],char ac[10]);
  538.             /* Read function and action names of a node         */
  539.  
  540. int   wstat(int net,LONG nn,float stat);
  541.             /* Modify node activation status                    */
  542.  
  543. int   winp(int net,LONG nn,float inp);
  544.             /* Modify node input                                */
  545.  
  546. int   werr(int net,LONG nn,float err);
  547.             /* Modify node error in EBP phase                   */
  548.  
  549. int   wbias(int net,LONG nn,float bias);
  550.             /* Modify node bias                                 */
  551.  
  552. int   wfun(int net,LONG nn,char fun[10],char ac[10]);
  553.             /* Modify node function and action                  */
  554.  
  555. int   rnconn(int net,LONG nn,LONG *ncl);
  556.             /* Read total number of links                       */
  557.  
  558. int   rconn(int net,LONG nn,LONG cl,float *wgt ,LONG *np);
  559.             /* Read node pointed and weigt of <cl> link         */
  560.             /* (Warn.: links for a node are numbered from 0 )   */
  561.  
  562. int   wwgt(int net,LONG nn,LONG cl,float wgt);
  563.             /* Modify weigt of <cl> link                        */
  564.             /* (Warn.: links for a node are numbered from 0 )   */
  565.  
  566. int   wnodp(int net,LONG nn,LONG cl,LONG np);
  567.             /* Modify node pointed by <cl> link                 */
  568.             /* (Warn.: links for a node are numbered from 0 )   */
  569.  
  570. int   wnconn(int net,LONG nn,LONG ncl);
  571.             /* Modify the total number of links                 */
  572.             /* (Warn.: links for a node are numbered from 0 )   */
  573.             /* (Warn.: we can only reduce total original links) */
  574. /*****************************************************************************/
  575.  
  576. /********************* ACTIVATION FUNCTIONS NAMES ****************************/
  577. /*                                                                            */
  578. /*   f1  : Unitary function : copy input to activation status                 */
  579. /*   f2  : Same as f1 but with memory : add 1/2 previous status to input      */
  580. /*   f3  : Sigmoid function with positiv and negativ value (0 centred)        */
  581. /*   f4  : Same as f3 but with memory                                         */
  582. /*   f5  : Sigmoid function with only positiv value (.5 centred)              */
  583. /*   f6  : Same as f5 but with memory                                         */
  584. /*                                                                            */
  585. /*   f7  : User defined (see below)                                           */
  586. /*   f8  : User defined (see below)                                           */
  587. /*   f9  : User defined (see below)                                           */
  588. /*   f10 : User defined (see below)                                           */
  589. /*                                                                            */
  590. /*   f13 : Sigmoid function as f3 but calculated (more exact but slower )     */
  591. /*   f15 : Sigmoid function as f5 but calculated (more exact but slower )     */
  592. /*                                                                            */
  593. /*   Warning :                                                                */
  594. /*   Sigmoid funct.(f3<->f6) and derivatives are founded  by look table (for  */
  595. /*   more speed) with .01 resolution.                                         */
  596. /******************************************************************************/
  597.  
  598. /*********************** ACTIONS AND USER DEFINED FUNCTION ********************/
  599.  
  600.  
  601. extern  int  a1(int net,LONG nn) ;
  602. extern  int  a2(int net,LONG nn) ;
  603. extern  int  a3(int net,LONG nn) ;
  604. extern  int  a4(int net,LONG nn) ;
  605. extern  int  a5(int net,LONG nn) ;
  606. extern  int  a6(int net,LONG nn) ;
  607.  
  608. extern  int  f7(int net,LONG nn,int f,float *d) ;
  609. extern  int  f8(int net,LONG nn,int f,float *d) ;
  610. extern  int  f9(int net,LONG nn,int f,float *d) ;
  611. extern  int  f10(int net,LONG nn,int f,float *d) ;
  612.  
  613. /* Parameters definition :                                                    */
  614. /*            net  : net number                                               */
  615. /*            nn   : node number                                              */
  616. /*            f    : flag function/derivative (0 func. , 1 der. for EBP phase)*/
  617. /*            *d   : buffer for return value of derivative                    */
  618.  
  619. /* Example of user definited function (unitary function):                     */
  620. /*                                                                            */
  621. /* f7(int net,LONG nn, int f, float *d)                                       */
  622. /*  {float buff;                                                              */
  623. /*   if (f==0) {rinp(net,nn,&buff);wstat(net,nn,buff);winp(net,nn,0);return;} */
  624. /*   if (f==1) {*d =1;return;}                                                */
  625. /*  }                                                                         */
  626.  
  627. /******************************************************************************/
  628.  
  629. /********************** Funzioni di supporto **********************************/
  630.  
  631. static void  motore(int nr,LONG strn, LONG stpn);
  632. static void  ebp   (int nr,LONG strn, LONG stpn);
  633. static char  far *allocamem(LONG n,LONG s);
  634. static int   deallocamem();
  635. static int   scantok(char tok[255],FILE *fp);
  636. static int   poschar(char *buff,char ch);
  637. static int   copys(char *buff,char *buff2,int lastpos);
  638. static void  errmess(int cod);
  639. static float sigma(float x);
  640. static float sigma2(float x);
  641. static float dsig(float x);
  642. static float dsig2(float x);
  643. static void  far *carfunz(char *tok);
  644. static char  *leggefunz(int (*fun)());
  645. static float randab(float ra,float rb);
  646. static void  fine();
  647.  
  648. /******************************************************************************/
  649.  
  650. /******************************************************************************/
  651. /*           Creazione , salvataggio e caricamento di tutte le reti           */
  652. /******************************************************************************/
  653.  
  654. /******************************************************************************/
  655. /*                   Nets saving and loading                                  */
  656. /*                                                                            */
  657. /* File format of nets saved  :                                               */
  658. /*                                                                            */
  659. /*                                                                            */
  660. /* first record : "totnets"/max_net_num/total_layers/                         */
  661. /* other record : "nnet"/net_num/total_nodes/total_links/                     */
  662. /*           or : "lay"/layer_num/                                            */
  663. /*           or : "node"/node_num/input/bias/stat/fun_name/ac_name/           */
  664. /*           or : "conn"/pointed_node;weight/...../pointed_node;weight/       */
  665. /* example :                                                                  */
  666. /*                totnets/10/300/                                             */
  667. /*                  nnet/1/12/36/                                             */
  668. /*                   lay/0/                                                   */
  669. /*                    node/1/0/0/0/f1/0/                                      */
  670. /*                    conn/10;0.66/11;0.3331/12;0.001/                        */
  671. /*                        :                                                   */
  672. /*                        :                                                   */
  673. /*                                                                            */
  674. /* - it's possible to continue record on more lines                           */
  675. /* - each field end with / character                                          */
  676. /* - input,bias,status,weigt are float , other integer                        */
  677. /* - fun_name and ac_name are strings                                         */
  678. /******************************************************************************/
  679.  
  680. /*************************** CARICA LA RETE da fileinp ************************/
  681.  
  682. loadnet(filei)
  683. char *filei;
  684. {
  685.   char tok[255];
  686.   char tok2[255];
  687.   char far *rets;
  688.   struct livello far *pliv;
  689.   struct livello far *liv;
  690.   struct nodo far *nodo;
  691.   int ret,nr;
  692.   int nliv;
  693.   LONG nn;LONG vd1;LONG vd2;LONG h;
  694.   LONG maxnn;
  695.   FILE    *fp;
  696.  
  697.   if (strlen(filei) != 0) strcpy(fileinp,filei);
  698.   fp= fopen(fileinp,"r");
  699.   if (fp == (void *)NULLO) {errmess(NOFILEI); fine();}
  700.  
  701.   if (flgstrr > 0) {deallocamem();flgstrr=0;}
  702.   for (;;)
  703.   {
  704.   ret=scantok(tok,fp);if (ret == NULLO) {errmess(NOTRETE);fine();}
  705.   if (strncmp(tok,"totnets",7) == 0)
  706.     {
  707.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NOTRETE);fine();}
  708.       totr=atoi(tok);
  709.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NOTLIV);fine();}
  710.       totl=atol(tok);
  711.       break;
  712.     }
  713.   }
  714.   rets=allocamem(totr+1,sizeof(struct rete));
  715.   if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  716.   r=(struct rete *)rets;
  717.   rets=allocamem(totl+1,sizeof(struct livello));
  718.   if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  719.   iniliv=(struct livello *)rets;
  720.   flgstrr=1;
  721.  
  722.   nr=1;
  723.   pliv=iniliv;
  724.  
  725.   for (;;)
  726.   {
  727.     ret=scantok(tok,fp);if (ret == NULLO) break;
  728.  
  729.     if (strncmp(tok,"nnet",4) == 0)
  730.     {
  731.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONUMR);fine();}
  732.       nr=atoi(tok);
  733.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NODIM); fine();}
  734.       (r+nr)->d1=atol(tok);
  735.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NODIM); fine();}
  736.       (r+nr)->d2=atol(tok);
  737.  
  738.       rets=allocamem((r+nr)->d1+1,sizeof(struct nodo));
  739.       if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  740.       (r+nr)->nodo = (struct nodo *)rets;
  741.       rets=allocamem((r+nr)->d2,sizeof(struct coll));
  742.       if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  743.       (r+nr)->inicoll = (struct coll *)rets;vd2=0;
  744.  
  745.       (r+nr)->maxliv=0;
  746.       (r+nr)->liv=pliv;
  747.       liv=(r+nr)->liv;
  748.       nodo=(r+nr)->nodo;
  749.       vd1=0;vd2=0;
  750.       flgrete++;
  751.     }
  752.  
  753.     if (strncmp(tok,"lay",3) == 0)
  754.     {
  755.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NOLIV);fine();}
  756.       nliv=atoi(tok); if (nliv > 99) {errmess(TOOLIV);fine();}
  757.       (liv+nliv)->sn=0;
  758.       if (nliv > (r+nr)->maxliv) (r+nr)->maxliv = nliv;
  759.       pliv=pliv+1;
  760.     }
  761.  
  762.     if (strncmp(tok,"node",4) == 0)
  763.     {
  764.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  765.       nn = atol(tok);if (vd1<nn) vd1=nn;
  766.       if (nn == 0) {errmess(NONODO);fine();}
  767.       if (nn > (r+nr)->d1) {errmess(NONODO);fine();}
  768.       if ((liv+nliv)->sn == 0) {(liv+nliv)->sn=nn; }
  769.       (liv+nliv)->en=nn;
  770.       h=0;
  771.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  772.       (*(nodo+nn)).inp = atof(tok);
  773.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  774.       (*(nodo+nn)).bias = atof(tok);
  775.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  776.       (*(nodo+nn)).stato = atof(tok);
  777.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  778.       (*(nodo+nn)).funz = carfunz(tok);
  779.       ret=scantok(tok,fp);if (ret == NULLO) {errmess(NONODO);fine();}
  780.       (*(nodo+nn)).azione = carfunz(tok);
  781.       (*(nodo+nn)).ncoll=0;
  782.       (*(nodo+nn)).dbias=0;
  783.       continue;
  784.     }
  785.     if (strncmp(tok,"conn",4) == 0) continue;
  786.     ret=poschar(tok,';');if (ret != -1)
  787.     {
  788.       if (h==0) {(*(nodo+nn)).coll = (r+nr)->inicoll+vd2;}
  789.       vd2++;if (vd2 > (r+nr)->d2) {errmess(TOOCOLL);fine();}
  790.       (*(nodo+nn)).ncoll++ ;
  791.       copys(tok2,tok,ret-1);
  792.       (*((*(nodo+nn)).coll+h)).nodo = atol(tok2);
  793.       copys(tok2,tok+ret+1,strlen(tok)-ret-1);
  794.       (*((*(nodo+nn)).coll+h)).peso = atof(tok2);
  795.       (*((*(nodo+nn)).coll+h)).dp = 0;
  796.       h++;
  797.     }
  798.   }
  799.   fclose(fp);
  800.   return 0;
  801. }
  802.  
  803.  
  804. /*************************  SCARICA LA RETE sul file fileout ******************/
  805.  
  806. savenet(fileo)
  807. char *fileo;
  808. {
  809.   LONG ncol=0;LONG nn, h;
  810.   int nliv,nr;
  811.   char *leggefunz();
  812.   FILE *fp;
  813.   struct livello far *liv;
  814.   struct nodo far *nodo;
  815.   struct coll far *coll;
  816.   if (strlen(fileo) != 0) strcpy(fileout,fileo);
  817.   fp = fopen(fileout,"w");
  818.   if (fp == (void *)NULLO) {errmess(NOFILEO); fine();}
  819.  
  820.   fprintf (fp,"totnets/%d/%ld/\n",totr,totl);
  821.   for (nr=1;nr<=totr;nr++)
  822.   {
  823.    liv=(r+nr)->liv;
  824.    nodo=(r+nr)->nodo;
  825.    fprintf(fp,"\nnnet/%d/%ld/%ld/\n",nr,(r+nr)->d1,(r+nr)->d2);
  826.    for (nliv=0; nliv<=(r+nr)->maxliv; nliv++)
  827.    {
  828.     fprintf (fp,"lay/%d/\n",nliv);
  829.     for(nn=(liv+nliv)->sn; nn<=(liv+nliv)->en; nn++)
  830.     {
  831.      fprintf (fp,"  node/%ld/%06.4f/%06.4f/%06.4f/%s/%s/\n",
  832.        nn,
  833.        (*(nodo+nn)).inp,
  834.        (*(nodo+nn)).bias,
  835.        (*(nodo+nn)).stato,
  836.        leggefunz((*(nodo+nn)).funz),
  837.        leggefunz((*(nodo+nn)).azione));
  838.     fprintf (fp,"    conn/");
  839.     for (h=0; h<(*(nodo+nn)).ncoll; h++)
  840.       {
  841.     fprintf (fp,"%ld;%06.4f/",
  842.     (*((*(nodo+nn)).coll+h)).nodo,
  843.     (*((*(nodo+nn)).coll+h)).peso);
  844.     ncol++; if (ncol > 6) {fprintf (fp,"\n        ");ncol=0;}
  845.       }
  846.     if (ncol <= 6) {fprintf (fp,"\n");ncol=0;}
  847.    }
  848.    }
  849.    }
  850.    fclose(fp);
  851.    return 0;
  852. }
  853.  
  854. /*************************  CREA RETI TUTTE UGUALI ****************************/
  855.  
  856. createallnet(tr,nliv,vn,vf,va)
  857. int tr;
  858. int nliv;
  859. LONG vn[];
  860. char vf[][10];
  861. char va[][10];
  862. {
  863.   int nr;
  864.   int vliv[1000];
  865.   if (tr > 1000) {errmess(TOONET);fine();}
  866.   for (nr=1;nr<=tr;nr++) {vliv[nr]=nliv;}
  867.   createstruct(tr,vliv);
  868.   for (nr=1;nr<=totr;nr++) {createnet(nr,vn,vf,va);}
  869.   return 0;
  870. }
  871.  
  872. /*************************  CREA LA STRUTTURA PER LE RETI *********************/
  873.  
  874. createstruct(tr,vliv)
  875. int tr;
  876. int vliv[];
  877. {
  878.   int i;
  879.   struct livello far *pliv;
  880.   char  far *rets;
  881.   totl=0;
  882.   totr=tr;
  883.   for (i=1;i<=totr;i++) { totl=totl+vliv[i]+1;  }
  884.   rets=allocamem(totr+1,sizeof(struct rete));
  885.   if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  886.   r=(struct rete *)rets;
  887.   rets=allocamem(totl+1,sizeof(struct livello));
  888.  
  889.   if ((long)rets == NULLO) {errmess(NOMEM);fine();}
  890.   iniliv=(struct livello *)rets;
  891.   pliv=iniliv;
  892.   for (i=1;i<=totr;i++)
  893.   {
  894.    (r+i)->maxliv=vliv[i];
  895.    (r+i)->liv=pliv;
  896.    pliv=pliv+vliv[i]+1;
  897.   }
  898.   flgstrr=1;
  899.   return 0;
  900. }
  901.  
  902. /*************************  CREA LA SINGOLA RETE ******************************/
  903.  
  904. createnet(nr,vn,vf,va)
  905. int nr;
  906. LONG vn[];
  907. char vf[][10];
  908. char va[][10];
  909. {
  910.   int i,tcoll,nliv;
  911.   LONG cnn,nn,h,ni;
  912.   char far *rets;
  913.   struct nodo    far *nodo;
  914.   struct coll    far *inicoll;
  915.   struct livello far *liv;
  916.  
  917.   if (flgstrr == 0) {errmess(NOSTRUCT);fine();}
  918.   if (nr > totr) {errmess(CREARETE);fine();}
  919.   cnn=1;tcoll=0;
  920.   liv=(r+nr)->liv;
  921.   nliv=(r+nr)->maxliv;
  922.   for (i=0;i<=nliv;i++)
  923.   {
  924.     (liv+i)->sn=cnn;
  925.     cnn=cnn+vn[i];
  926.     (liv+i)->en=cnn-1;
  927.     if (i != nliv) {tcoll=tcoll+(vn[i] * vn[i+1]);}
  928.   }
  929.   (r+nr)->d1=cnn-1;
  930.   (r+nr)->d2=tcoll;
  931.   rets=allocamem((r+nr)->d1+1,sizeof(struct nodo));
  932.   if (rets == NULLO) {errmess(NOMEM);fine();}
  933.   (r+nr)->nodo = (struct nodo *)rets;
  934.   nodo=(r+nr)->nodo;
  935.   rets=allocamem((r+nr)->d2+1,sizeof(struct coll));
  936.   if (rets == NULLO) {errmess(NOMEM);fine();}
  937.   (r+nr)->inicoll = (struct coll *)rets;
  938.   inicoll = (r+nr)->inicoll;
  939.   tcoll=0;
  940.   for (i=0;i<=nliv;i++)
  941.   {
  942.     for (nn=(liv+i)->sn; nn<=(liv+i)->en; nn++)
  943.     {
  944.       (*(nodo+nn)).dbias=0;
  945.       (*(nodo+nn)).bias=0;
  946.       (*(nodo+nn)).inp=0;
  947.       (*(nodo+nn)).stato=0;
  948.       (*(nodo+nn)).funz=carfunz(vf[i]);
  949.       (*(nodo+nn)).azione=carfunz(va[i]);
  950.       (*(nodo+nn)).ncoll=0;
  951.       (*(nodo+nn)).coll=inicoll+tcoll;
  952.       if (i < nliv)
  953.       {
  954.       h=0;
  955.       for (ni=(liv+i+1)->sn; ni<=(liv+i+1)->en; ni++)
  956.       {
  957.     (*((*(nodo+nn)).coll+h)).nodo = ni;
  958.     (*((*(nodo+nn)).coll+h)).peso = randab(randa,randb);
  959.     (*((*(nodo+nn)).coll+h)).dp = 0;
  960.     tcoll++;h++;
  961.       }
  962.       (*(nodo+nn)).ncoll=h;
  963.       }
  964.     }
  965.   }
  966.  flgrete++;
  967.  return 0;
  968. }
  969.  
  970. /*************************  REINIZIALIZZA E COPIA RETI ************************/
  971.  
  972. ininet(int nr)
  973. {
  974.   LONG nn,h;
  975.   struct nodo    far *nodo;
  976.   if (flgstrr == 0) {errmess(NOSTRUCT);fine();}
  977.   if (nr > totr) return -1;
  978.   nodo=(r+nr)->nodo;
  979.   for (nn=1; nn<=(r+nr)->d1; nn++)
  980.   {
  981.       (*(nodo+nn)).dbias=0;
  982.       (*(nodo+nn)).bias=0;
  983.       (*(nodo+nn)).inp=0;
  984.       (*(nodo+nn)).stato=0;
  985.       for (h=0;h<(*(nodo+nn)).ncoll;h++)
  986.       {
  987.     (*((*(nodo+nn)).coll+h)).peso = randab(randa,randb);
  988.     (*((*(nodo+nn)).coll+h)).dp = 0;
  989.       }
  990.    }
  991.    return 0;
  992. }
  993.  
  994. copynet(int nra,int nrb)
  995. {
  996.   LONG nn,h;
  997.   struct nodo   far *nodoa;
  998.   struct nodo   far *nodob;
  999.   if (flgstrr == 0) {errmess(NOSTRUCT);fine();}
  1000.   if (nra > totr) return -1;
  1001.   if (nrb > totr) return -1;
  1002.   nodoa=(r+nra)->nodo;
  1003.   nodob=(r+nrb)->nodo;
  1004.   for (nn=1; nn<=(r+nra)->d1; nn++)
  1005.   {
  1006.       if (nn > (r+nrb)->d1) return -1;
  1007.       (*(nodob+nn)).dbias=0;
  1008.       (*(nodob+nn)).bias=(*(nodoa+nn)).bias;
  1009.       (*(nodob+nn)).funz=(*(nodoa+nn)).funz;
  1010.       (*(nodob+nn)).azione=(*(nodoa+nn)).azione;
  1011.       (*(nodob+nn)).inp=0;
  1012.       (*(nodob+nn)).stato=0;
  1013.       for (h=0;h<(*(nodoa+nn)).ncoll;h++)
  1014.       {
  1015.     if (h > (*(nodob+nn)).ncoll) break;
  1016.     (*((*(nodob+nn)).coll+h)).peso = (*((*(nodoa+nn)).coll+h)).peso;
  1017.     (*((*(nodob+nn)).coll+h)).dp = 0;
  1018.       }
  1019.    }
  1020.    return 0;
  1021. }
  1022.  
  1023. cancnets()
  1024. {
  1025.   deallocamem();
  1026.   return 0;
  1027. }
  1028.  
  1029. /*************************  ROUTINES PER L'ALLOCAZIONE DELLA MEMORIA **********/
  1030.  
  1031. char far *allocamem(LONG n,LONG s)
  1032. {
  1033.   char far *iseg;
  1034.   if (flgdeb>0) printf("Alloc  %d  bytes ",n*s);
  1035. # ifdef B16
  1036.     if (n*s > 0xFFFF) return(NULLO);
  1037. # endif
  1038.   iseg = ALLOCA(n,s);
  1039.   if (flgdeb>0) {if ((long)iseg != 0) printf("   starting %p\r\n",iseg);}
  1040.   return(iseg);
  1041. }
  1042.  
  1043. deallocamem()
  1044. {
  1045.   int nr;
  1046.   for (nr=1;nr<=totr;nr++)
  1047.     {
  1048.      if ((r+nr)->nodo != NULLO)  LIBERA((void far *)(r+nr)->nodo);
  1049.      if ((r+nr)->inicoll != NULLO) LIBERA((void far *)(r+nr)->inicoll);
  1050.     }
  1051.   if ( r != NULLO) LIBERA((void far *)r);
  1052.   if ( iniliv != NULLO) LIBERA((void far *)iniliv);
  1053.   return 0;
  1054. }
  1055.  
  1056. /*************************  ROUTINES DI SUPPORTO ******************************/
  1057.  
  1058. scantok(char tok[255],FILE *fp)
  1059. {
  1060.   int i,len;
  1061.   char ch;
  1062.   i=0;tok[0]='\0';
  1063.   for(;;)
  1064.   {
  1065.     ch=getc(fp);
  1066.     if (ch == EOF) {len=NULLO; break;}
  1067.     if ((ch == '/') || isspace(ch))
  1068.       {if (i>0) { tok[i]='\0';len=i;i=0;break;} else continue; }
  1069.     tok[i]=ch;i++;tok[i]='\0';if (i>254) return NULLO;
  1070.   }
  1071.   return(len);
  1072. }
  1073.  
  1074. poschar(char *buff,char ch)
  1075. {
  1076.   int i;
  1077.   for (i=0;i<strlen(buff);i++)
  1078.    {if (*(buff+i) == ch)  return(i);}
  1079.   return(-1);
  1080. }
  1081.  
  1082. copys(char *buff1,char *buff2,int lastpos)
  1083. {
  1084.   int i;
  1085.   for (i=0;i<=lastpos;i++) *(buff1+i) = *(buff2+i);
  1086.   *(buff1+lastpos+1) =0;
  1087.   return 0;
  1088. }
  1089.  
  1090. float randab(float ra,float rb)
  1091. {
  1092.  float num;
  1093.  num = rand()&0x7FFF; num = num/MAX_RAND;
  1094.  return (num * (rb-ra) + ra);
  1095. }
  1096.  
  1097. /******************************************************************************/
  1098. /*                             Nucleo operativo                               */
  1099. /******************************************************************************/
  1100.  
  1101. /*********************** ELABORAZIONE ATTRAVERSO I LIVELLI ********************/
  1102.  
  1103. produce(nr,inpdat,outdat)
  1104. int nr;
  1105. char *inpdat;
  1106. char *outdat;
  1107. {
  1108.  int ret,maxliv;
  1109.  LONG i,ninp,nout;
  1110.  float *rets;
  1111.  float *vinp,*vout,*vdat;
  1112.  FILE *fpinp;
  1113.  FILE *fpout;
  1114.  struct livello far *liv;
  1115.  if (nr > totr) {errmess(CREARETE);fine();}
  1116.  liv=(r+nr)->liv;
  1117.  maxliv=(r+nr)->maxliv;
  1118.  if (strlen(inpdat)==0) fpinp=stdin;
  1119.   else
  1120.   {fpinp=fopen(inpdat,"r");
  1121.   if (fpinp==NULLO) printf("Non puo' aprire il file di dati %s\r\n",inpdat);
  1122.   return -1;}
  1123.  if (strlen(outdat)==0) fpout=stdout;
  1124.   else
  1125.   {fpout=fopen(outdat,"w");
  1126.   if (fpout==NULLO) printf("Non puo' aprire il file di dati %s\r\n",outdat);
  1127.   return -1;}
  1128.  if (flgrete < nr) {printf("\n Caric. prima la rete (o crearla) !");return -1;}
  1129.   ninp=(liv+0)->en-(liv+0)->sn+1; nout=(liv+maxliv)->en-(liv+maxliv)->sn+1;
  1130.   rets=calloc(ninp+1,sizeof(*vinp));
  1131.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vinp=rets;
  1132.   rets=calloc(nout+1,sizeof(*vout));
  1133.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vout=rets;
  1134.   rets=calloc(nout+1,sizeof(*vdat));
  1135.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vdat=rets;
  1136.  
  1137.  for (;;)
  1138.  {
  1139.    printf("\n>");
  1140.    for (i=1;i<=ninp;i++)
  1141.        {ret=fscanf(fpinp,"%f",&vinp[i]);if (ret < 1) goto fine;}
  1142.    compute(nr,vinp,vout,vdat);
  1143.    for (i=1;i<=nout;i++) fprintf(fpout,"\n%7.3f",vout[i]);
  1144.  }
  1145.  fine:
  1146.  free(vinp);free(vout);free(vdat);
  1147.  return 0;
  1148. }
  1149.  
  1150.  
  1151. float compute(nr,vinp,vout,vdat)
  1152. int nr;
  1153. float vinp[];
  1154. float vout[];
  1155. float vdat[];
  1156. {
  1157.  int maxliv;
  1158.  LONG i,nl,k;
  1159.  float err,errq;
  1160.  struct nodo far *nodo;
  1161.  struct livello far *liv;
  1162.  errq=0;
  1163.   if (nr > totr) {errmess(CREARETE);fine();}
  1164.  nodo=(r+nr)->nodo;
  1165.  maxliv=(r+nr)->maxliv;
  1166.  liv=(r+nr)->liv;
  1167.  for (i=(liv+0)->sn; i<=(liv+0)->en; i++)
  1168.    {k=i-(liv+0)->sn+1; (*(nodo+i)).inp=vinp[k]; }
  1169.  propagate(nr,0,maxliv);
  1170.  for (i=(liv+maxliv)->sn; i<=(liv+maxliv)->en; i++)
  1171.    {
  1172.    k=i-(liv+maxliv)->sn+1;
  1173.    vout[k]=(*(nodo+i)).stato;
  1174.    err=(vout[k] - vdat[k]) ;vdat[k]=err;
  1175.    errq=errq+(float)pow((double)err,(double)2);
  1176.    }
  1177.  return(errq/k);
  1178. }
  1179.  
  1180. propagate(int nr,int liva,int livb)
  1181. {
  1182.  int nl;
  1183.  LONG strn,stpn;
  1184.  struct livello far *liv;
  1185.  if (nr > totr) {errmess(CREARETE);fine();}
  1186.  liv=(r+nr)->liv;
  1187.  for (nl=liva ;nl<=livb; nl++)
  1188.    {strn=(liv+nl)->sn;stpn=(liv+nl)->en;motore(nr,strn,stpn);}
  1189.  return 0;
  1190. }
  1191.  
  1192.  
  1193. /********************** CORREZIONE ALL'INDIETRO *******************************/
  1194.  
  1195.  
  1196. param(char *nome,char *val)
  1197. {
  1198.  if (strncmp(nome,"ne",2) == 0) {nep=atoi(val);return 0;}
  1199.  if (strncmp(nome,"er",2) == 0) {minerr=atof(val);return 0;}
  1200.  if (strncmp(nome,"ep",2) == 0) {epsl=atof(val);return 0;}
  1201.  if (strncmp(nome,"mo",2) == 0) {alfa=atof(val);return 0;}
  1202.  if (strncmp(nome,"ra",2) == 0) {randa=atof(val);return 0;}
  1203.  if (strncmp(nome,"rb",2) == 0) {randb=atof(val);return 0;}
  1204.  if (strncmp(nome,"fb",2) == 0) {flgbias=atoi(val);return 0;}
  1205.  if (strncmp(nome,"fd",2) == 0) {flgdeb=atoi(val);return 0;}
  1206.  return -1;
  1207. }
  1208.  
  1209.  
  1210. float train(nr,fileese)
  1211. int nr;
  1212. char *fileese;
  1213. {
  1214.   int ret,maxliv;
  1215.   char tok[255];
  1216.   LONG ep,ninp,nout,es,i,nn;
  1217.   float *vinp,*vout,*vdat;
  1218.   float err, errep;
  1219.   float *rets;
  1220.   FILE    *fp;
  1221.   struct livello far *liv;
  1222.   if (nr > totr) {errmess(CREARETE);fine();}
  1223.   liv=(r+nr)->liv;
  1224.   maxliv=(r+nr)->maxliv;
  1225.   ninp=(liv+0)->en-(liv+0)->sn+1; nout=(liv+maxliv)->en-(liv+maxliv)->sn+1;
  1226.   rets=calloc(ninp+1,sizeof(*vinp));
  1227.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vinp=rets;
  1228.   rets=calloc(nout+1,sizeof(*vout));
  1229.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vout=rets;
  1230.   rets=calloc(nout+1,sizeof(*vdat));
  1231.   if (rets == NULLO) {errmess(NOMEMV);fine();}; vdat=rets;
  1232.   fp = fopen(fileese,"r");
  1233.   if (fp == NULLO) {errmess(NOFILEES); fine();}
  1234.   for (ep=1;ep<=nep;ep++)
  1235.   {
  1236.    errep=0;es=0;
  1237.    for (;;)
  1238.    {
  1239.     if (scantok(tok,fp) == NULLO) break;
  1240.     vinp[1]=atof(tok) ;
  1241.     for (i=2;i<=ninp;i++)
  1242.     {
  1243.       if (scantok(tok,fp) == NULLO) {errmess(ERRESE);fine();}
  1244.       vinp[i]=atof(tok) ;
  1245.     }
  1246.     for (i=1;i<=nout;i++)
  1247.     {
  1248.       if (scantok(tok,fp) == NULLO) {errmess(ERRESE);fine();}
  1249.       vdat[i]=atof(tok) ;
  1250.     }
  1251.     err=compute(nr,vinp,vout,vdat);
  1252.     learn(nr,vdat);
  1253.     errep=errep+err;
  1254.     es++;
  1255.    }
  1256.   rewind(fp);
  1257.   errep=errep/es;
  1258.   if (errep <= minerr) break;
  1259.   if (flgdeb>=2) printf("\n Epoch      %5ld    Aver.q.err. %7.4f ",ep,errep);
  1260.   }
  1261.   if (flgdeb<2) printf("\n Tot.Epoch %5ld     Aver.q.err. %7.4f ",ep,errep);
  1262.   free(vinp);free(vout);free(vdat);
  1263.   fclose(fp);
  1264.   return errep;
  1265. }
  1266.  
  1267.  
  1268.  
  1269. learn(nr,verr)
  1270. int nr;
  1271. float verr[];
  1272. {
  1273.  LONG i,nl,k;
  1274.  int maxliv;
  1275.  struct nodo far *nodo;
  1276.  struct livello far *liv;
  1277.  if (nr > totr) {errmess(CREARETE);fine();}
  1278.  nodo=(r+nr)->nodo;
  1279.  maxliv=(r+nr)->maxliv;
  1280.  liv=(r+nr)->liv;
  1281.  for (i=(liv+maxliv)->sn; i<=(liv+maxliv)->en; i++)
  1282.    { k=i-(liv+maxliv)->sn+1; (*(nodo+i)).inp = verr[k];}
  1283.  backprop(nr,0,maxliv);
  1284.  return 0;
  1285. }
  1286.  
  1287. backprop(int nr,int liva,int livb)
  1288. {
  1289.  LONG nl,i;
  1290.  LONG strn,stpn;
  1291.  struct nodo far *nodo;
  1292.  struct livello far *liv;
  1293.  if (nr > totr) {errmess(CREARETE);fine();}
  1294.  nodo=(r+nr)->nodo;
  1295.  liv=(r+nr)->liv;
  1296.  for (nl=livb ;nl>=liva; nl--)
  1297.    {strn=(liv+nl)->sn;stpn=(liv+nl)->en;ebp(nr,strn,stpn);}
  1298.  for (nl=livb ;nl>=liva; nl--)
  1299.    {for (i=(liv+nl)->sn; i<=(liv+nl)->en; i++) {(*(nodo+i)).inp = 0;}}
  1300.  return 0;
  1301. }
  1302.  
  1303. backproperr(int nr,int liva,int livb)
  1304. {
  1305.  LONG nl,i;
  1306.  LONG strn,stpn;
  1307.  struct nodo far *nodo;
  1308.  struct livello far *liv;
  1309.  if (nr > totr) {errmess(CREARETE);fine();}
  1310.  nodo=(r+nr)->nodo;
  1311.  liv=(r+nr)->liv;
  1312.  for (nl=livb ;nl>=liva; nl--)
  1313.    {strn=(liv+nl)->sn;stpn=(liv+nl)->en;ebp(nr,strn,stpn);}
  1314.  for (nl=livb ;nl>=liva; nl--)
  1315.    {for (i=(liv+nl)->sn; i<=(liv+nl)->en; i++) {(*(nodo+i)).inp = 0;}}
  1316.  return 0;
  1317. }
  1318.  
  1319. cancerr(int nr,int liva,int livb)
  1320. {
  1321.  LONG nl,i;
  1322.  LONG strn,stpn;
  1323.  struct nodo far *nodo;
  1324.  struct livello far *liv;
  1325.  if (nr > totr) {errmess(CREARETE);fine();}
  1326.  nodo=(r+nr)->nodo;
  1327.  liv=(r+nr)->liv;
  1328.  for (nl=livb ;nl>=liva; nl--)
  1329.    {for (i=(liv+nl)->sn; i<=(liv+nl)->en; i++) {(*(nodo+i)).inp = 0;}}
  1330.  return 0;
  1331. }
  1332.  
  1333. /******************************   MOTORE  ***********************************/
  1334.  
  1335. void motore(nr,strn,stpn)
  1336. int nr;
  1337. LONG strn,stpn;
  1338. {
  1339.   LONG nn; LONG h; LONG i; LONG cc;
  1340.   float b;
  1341.   struct nodo    far *nodo;
  1342.   struct nodo    far *nodonn;
  1343.   struct coll    far *collnn;
  1344. /*
  1345.   if (strn == 0) strn = 1;
  1346.   if (stpn  == 0) stpn  = (r+nr)->d1;
  1347. */
  1348.     for(nn=strn; nn<=stpn; nn++)
  1349.     {
  1350.       nodo = (r+nr)->nodo;
  1351.       nodonn = nodo+nn;
  1352.       if ((*nodonn).funz != 0)   (*((*nodonn).funz))(nr,nn,0,&b);
  1353.       if ((*nodonn).azione != 0) (*((*nodonn).azione))(nr,nn);
  1354.       collnn = (*nodonn).coll;
  1355.       for (h=0; h<(*nodonn).ncoll; h++)
  1356.       {
  1357.     i=(*(collnn+h)).nodo;
  1358.     if (i != 0)
  1359.     { (*(nodo+i)).inp=(*(nodo+i)).inp +
  1360.             ((*nodonn).stato * (*(collnn+h)).peso); }
  1361.       }
  1362.     }
  1363. }
  1364. /*-*/
  1365. /************************* ERROR BACK PROPAGATION *****************************/
  1366.  
  1367. void ebp(nr,strn,stpn)
  1368. int nr;
  1369. LONG strn,stpn;
  1370. {
  1371.   int ret;
  1372.   LONG nn; LONG h; LONG i; LONG cc;
  1373.   float dd, dpeso, peso, erri, errnn, dfuni, dp,dfunn,ddnn,dbias,bias,db;
  1374.   struct nodo    far *nodo;
  1375.   struct nodo    far *nodonn;
  1376.   struct coll    far *collnn;
  1377. /*
  1378.   if (strn == 0) strn = 1;
  1379.   if (stpn  == 0) stpn  = (r+nr)->d1;
  1380. */
  1381.     for(nn=strn; nn<=stpn; nn++)
  1382.     {
  1383.       nodo = (r+nr)->nodo;
  1384.       nodonn = nodo+nn;
  1385.       collnn = (*nodonn).coll;
  1386.       errnn = 0;
  1387.       for (h=0; h<(*nodonn).ncoll; h++)
  1388.      {
  1389.       i=(*(collnn+h)).nodo; peso=(*(collnn+h)).peso;dp=(*(collnn+h)).dp;
  1390.       if ((i != 0) && ((*(nodo+i)).inp != 0))
  1391.       {
  1392.       erri = (*(nodo+i)).inp;
  1393.       (*((*(nodo+i)).funz))(nr,i,1,&dfuni);
  1394.       dd = (erri * dfuni)   ;
  1395.       errnn = errnn + (dd * peso) ;
  1396.       dpeso = - ((epsl * dd) * ((*nodonn).stato ));
  1397.       dpeso=dpeso+(dp*alfa); peso=peso+dpeso; if (peso == 0) peso=.000001;
  1398.       (*(collnn+h)).peso = peso ; (*(collnn+h)).dp=dpeso;
  1399.       }
  1400.      }
  1401.      errnn = ((*nodonn).inp) + errnn;
  1402.      (*nodonn).inp =  errnn;
  1403.  
  1404.      if (flgbias == 1)
  1405.      {
  1406.      bias=(*nodonn).bias;db=(*nodonn).dbias;
  1407.      (*((*nodonn).funz))(nr,nn,1,&dfunn);
  1408.      ddnn = (errnn * dfunn)   ;
  1409.      dbias = - (epsl * ddnn) ;
  1410.      dbias=dbias+(db*alfa); bias=bias+dbias;
  1411.      (*nodonn).bias = bias ; (*nodonn).dbias=dbias;
  1412.      }
  1413.     }
  1414. }
  1415.  
  1416. /*-*/
  1417.  
  1418.  
  1419. /***************************** FUNZIONI ED AZIONI *****************************/
  1420.  
  1421. /*****************************     FUNZIONI       *****************************/
  1422.  
  1423. f1(int nr,LONG nn,int f,float *b)
  1424. /* Funzione unitaria sposta semplicemente input su stato  */
  1425. {
  1426.  struct nodo    far *nodo;
  1427.  nodo=(r+nr)->nodo;
  1428.  if (f == 1) { *b = 1;return (0);}  /* derivata */
  1429.  (*(nodo+nn)).stato = (*(nodo+nn)).inp+(*(nodo+nn)).bias ;
  1430.  (*(nodo+nn)).inp = 0;
  1431.  return (0);
  1432. }
  1433.  
  1434. f2(int nr,LONG nn,int f,float *b)
  1435. /* Come f1 ma con memoria */
  1436. /* tempo di dimezz. pari a un ciclo */
  1437. {
  1438.  struct nodo    far *nodo;
  1439.  nodo=(r+nr)->nodo;
  1440.  if (f == 1) { *b = 1;return (0);}  /* derivata */
  1441.  (*(nodo+nn)).stato = (((*(nodo+nn)).inp)+(*(nodo+nn)).bias+((*(nodo+nn)).stato / 2));
  1442.  (*(nodo+nn)).inp = 0;
  1443.  return (0);
  1444. }
  1445.  
  1446.  
  1447.  
  1448. f3(int nr,LONG nn,int f,float *b)
  1449. /* Funzione sigmoide centrata sullo 0 e con valori da -1 a 1        */
  1450. /* funzione tabulata corrispondente alla formula y=(exp(x)-1)/(exp(x)+1) */
  1451. {
  1452.  struct nodo    far *nodo;
  1453.  nodo=(r+nr)->nodo;
  1454.  if (f == 1) { *b = (dsig((*(nodo+nn)).stato));return (0);}  /* derivata */
  1455.  (*(nodo+nn)).stato = sigma((*(nodo+nn)).inp+(*(nodo+nn)).bias) ;
  1456.  (*(nodo+nn)).inp = 0;
  1457.  return (0);
  1458. }
  1459.  
  1460. f4(int nr,LONG nn,int f,float *b)
  1461. /* Come f3 ma con memoria */
  1462. /* tempo di dimezz. pari a un ciclo */
  1463. {
  1464.  struct nodo    far *nodo;
  1465.  nodo=(r+nr)->nodo;
  1466.  if (f == 1) { *b = (dsig(((*(nodo+nn)).stato)));return (0);}  /* derivata */
  1467.  (*(nodo+nn)).stato = sigma(((*(nodo+nn)).inp)+(*(nodo+nn)).bias+ ((*(nodo+nn)).stato / 2));
  1468.  (*(nodo+nn)).inp = 0;
  1469.  return (0);
  1470. }
  1471.  
  1472.  
  1473.  
  1474. f5(int nr,LONG nn,int f,float *b)
  1475. /* Funzione sigmoide centrata sullo 0 ma con valori da 0 a 1 */
  1476. /* funzione tabulata corrisp. alla formula Y=1/1+exp(-x) */
  1477. {
  1478.  struct nodo    far *nodo;
  1479.  nodo=(r+nr)->nodo;
  1480.  if (f == 1) { *b = (dsig2(((*(nodo+nn)).stato)));return (0);}  /* derivata */
  1481.  (*(nodo+nn)).stato = sigma2((*(nodo+nn)).inp+(*(nodo+nn)).bias);
  1482.  (*(nodo+nn)).inp = 0;
  1483.  return (0);
  1484. }
  1485.  
  1486. f6(int nr,LONG nn,int f,float *b)
  1487. /* Come f5 ma con memoria */
  1488. /* tempo di dimezz. pari a un ciclo */
  1489. {
  1490.  struct nodo    far *nodo;
  1491.  nodo=(r+nr)->nodo;
  1492.  if (f == 1) { *b = (dsig2(((*(nodo+nn)).stato)));return (0);}  /* derivata */
  1493.  (*(nodo+nn)).stato = sigma2(((*(nodo+nn)).inp)+(*(nodo+nn)).bias+ ((*(nodo+nn)).stato / 2));
  1494.  (*(nodo+nn)).inp = 0;
  1495.  return (0);
  1496. }
  1497.  
  1498. f13(int nr,LONG nn,int f,float *b)
  1499. /* Funzione sigmoide centrata sullo 0 e con valori da -1 a 1        */
  1500. /* funzione calcolata secondo la formula y=(exp(x)-1)/(exp(x)+1) */
  1501. /* derivata in funzione dello stato : -(y+1)(y-1)/2       */
  1502. {
  1503.  double x,ex;
  1504.  float y;
  1505.  struct nodo    far *nodo;
  1506.  nodo=(r+nr)->nodo;
  1507.  if (f == 1) { y = (*(nodo+nn)).stato;
  1508.           *b = -(y+1)*(y-1)/2  ;return (0);}  /* derivata */
  1509.  x = (*(nodo+nn)).inp+(*(nodo+nn)).bias ; ex = exp(x);
  1510.  (*(nodo+nn)).stato = (float)((ex-1)/(ex+1)) ;
  1511.  (*(nodo+nn)).inp = 0;
  1512.  return (0);
  1513. }
  1514.  
  1515. f15(int nr,LONG nn,int f,float *b)
  1516. /* Funzione sigmoide centrata sullo 0 ma con valori da 0 a 1 */
  1517. /* cioe' traslata in alto e con range dimezzato */
  1518. /* funzione calcolata secondo la formula Y=1/1+exp(-x) */
  1519. /* derivata in funzione dello stato : y(1-y) */
  1520. {
  1521.  double x,ex;
  1522.  float y;
  1523.  struct nodo    far *nodo;
  1524.  nodo=(r+nr)->nodo;
  1525.  if (f == 1) { y = (*(nodo+nn)).stato;
  1526.           *b = y*(1 - y);  return (0);}   /* derivata */
  1527.  x = (*(nodo+nn)).inp+(*(nodo+nn)).bias; ex = exp(-x);
  1528.  (*(nodo+nn)).stato = (float)(1/(1+ex));
  1529.  (*(nodo+nn)).inp = 0;
  1530.  return (0);
  1531. }
  1532.  
  1533. /********************** RUTINES DI SERVIZIO PER LE FUNZ.***********************/
  1534.  
  1535. /* Trasformazione sigma non lineare normalizzata all'int. -100.. 100   */
  1536.  
  1537. float sigma(float x)
  1538. {
  1539.  /* valori della funz. sigmoide -100..100 per attivazione 0..599 */
  1540.  /* per attiv.  -599..0  si hanno gli stessi valori ma negativi  */
  1541.  /* cioe' se x>0 y=T(x) se x<0 y=-T(x)                           */
  1542.  
  1543. static float semisig[] =
  1544. {
  1545. .00,.00,.01,.01,.02,.02,.03,.03,.04,.04,.05,.05,.06,.06,.07,.07,.08,.08,.09,.09,
  1546. .10,.10,.11,.11,.12,.12,.13,.13,.14,.14,.15,.15,.16,.16,.17,.17,.18,.18,.19,.19,
  1547. .20,.20,.21,.21,.22,.22,.23,.23,.24,.24,.24,.25,.25,.26,.26,.27,.27,.28,.28,.29,
  1548. .29,.30,.30,.30,.31,.31,.32,.32,.33,.33,.34,.34,.35,.35,.35,.36,.36,.37,.37,.38,
  1549. .38,.38,.39,.39,.40,.40,.41,.41,.41,.42,.42,.43,.43,.43,.44,.44,.45,.45,.45,.46,
  1550. .46,.47,.47,.47,.48,.48,.49,.49,.49,.50,.50,.50,.51,.51,.52,.52,.52,.53,.53,.53,
  1551. .54,.54,.54,.55,.55,.55,.56,.56,.56,.57,.57,.58,.58,.58,.58,.59,.59,.59,.60,.60,
  1552. .60,.61,.61,.61,.62,.62,.62,.63,.63,.63,.64,.64,.64,.64,.65,.65,.65,.66,.66,.66,
  1553. .66,.67,.67,.67,.68,.68,.68,.68,.69,.69,.69,.69,.70,.70,.70,.70,.71,.71,.71,.71,
  1554. .72,.72,.72,.72,.73,.73,.73,.73,.74,.74,.74,.74,.74,.75,.75,.75,.75,.76,.76,.76,
  1555. .76,.76,.77,.77,.77,.77,.77,.78,.78,.78,.78,.78,.79,.79,.79,.79,.79,.80,.80,.80,
  1556. .80,.80,.80,.81,.81,.81,.81,.81,.81,.82,.82,.82,.82,.82,.82,.83,.83,.83,.83,.83,
  1557. .83,.84,.84,.84,.84,.84,.84,.84,.85,.85,.85,.85,.85,.85,.85,.86,.86,.86,.86,.86,
  1558. .86,.86,.86,.87,.87,.87,.87,.87,.87,.87,.87,.88,.88,.88,.88,.88,.88,.88,.88,.88,
  1559. .89,.89,.89,.89,.89,.89,.89,.89,.89,.89,.90,.90,.90,.90,.90,.90,.90,.90,.90,.90,
  1560. .91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.92,.92,.92,.92,.92,.92,.92,.92,
  1561. .92,.92,.92,.92,.92,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,.93,
  1562. .94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.95,.95,.95,
  1563. .95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.96,.96,
  1564. .96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,
  1565. .96,.96,.96,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,
  1566. .97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.98,.98,.98,
  1567. .98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,
  1568. .98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,
  1569. .98,.98,.98,.98,.98,.98,.98,.98,.98,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1570. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1571. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1572. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1573. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1574. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99
  1575. };
  1576.  int ax; float y;
  1577.  ax = (int) (fabs(x)*100);
  1578.  if (ax > 599) {y = 1;}
  1579.  else {y= semisig[ax];}
  1580.  if (x < 0) return(-y);
  1581.  return(y);
  1582. }
  1583.  
  1584. /* trasformazione non lineare sigma2 normalizzata all'int. 0..1  */
  1585.  
  1586. float sigma2(float x)
  1587. {
  1588.  /* valori della funz. sigmoide 0..100 per attivaz.  0..511   */
  1589.  /* per attiv. -511..0 si ha 100-stessi valori                */
  1590.  /* cioe' se x>0 y=T(x) se x<0 y=100-T(x)                     */
  1591.  
  1592. static float semisig2[] =
  1593. {
  1594. .50,.50,.50,.51,.51,.51,.51,.52,.52,.52,.52,.53,.53,.53,.53,.54,.54,.54,.54,.55,
  1595. .55,.55,.55,.56,.56,.56,.56,.57,.57,.57,.57,.58,.58,.58,.58,.59,.59,.59,.59,.60,
  1596. .60,.60,.60,.61,.61,.61,.61,.62,.62,.62,.62,.62,.63,.63,.63,.63,.64,.64,.64,.64,
  1597. .65,.65,.65,.65,.65,.66,.66,.66,.66,.67,.67,.67,.67,.67,.68,.68,.68,.68,.69,.69,
  1598. .69,.69,.69,.70,.70,.70,.70,.70,.71,.71,.71,.71,.72,.72,.72,.72,.72,.73,.73,.73,
  1599. .73,.73,.73,.74,.74,.74,.74,.74,.75,.75,.75,.75,.75,.76,.76,.76,.76,.76,.76,.77,
  1600. .77,.77,.77,.77,.78,.78,.78,.78,.78,.78,.79,.79,.79,.79,.79,.79,.80,.80,.80,.80,
  1601. .80,.80,.81,.81,.81,.81,.81,.81,.81,.82,.82,.82,.82,.82,.82,.82,.83,.83,.83,.83,
  1602. .83,.83,.83,.84,.84,.84,.84,.84,.84,.84,.85,.85,.85,.85,.85,.85,.85,.85,.86,.86,
  1603. .86,.86,.86,.86,.86,.86,.87,.87,.87,.87,.87,.87,.87,.87,.87,.88,.88,.88,.88,.88,
  1604. .88,.88,.88,.88,.88,.89,.89,.89,.89,.89,.89,.89,.89,.89,.89,.90,.90,.90,.90,.90,
  1605. .90,.90,.90,.90,.90,.90,.91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.91,.92,.92,
  1606. .92,.92,.92,.92,.92,.92,.92,.92,.92,.92,.92,.92,.93,.93,.93,.93,.93,.93,.93,.93,
  1607. .93,.93,.93,.93,.93,.93,.93,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,.94,
  1608. .94,.94,.94,.94,.94,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,.95,
  1609. .95,.95,.95,.95,.95,.95,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,
  1610. .96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.96,.97,.97,.97,.97,.97,.97,.97,.97,
  1611. .97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,.97,
  1612. .97,.97,.97,.97,.97,.97,.97,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,
  1613. .98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,
  1614. .98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.98,.99,
  1615. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1616. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1617. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1618. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1619. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,
  1620. .99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99,.99
  1621. };
  1622.  int ax; float y;
  1623.  ax = (int) (fabs(x)*100);
  1624.  if (ax > 539) {y = 1;}
  1625.  else {y= semisig2[ax];}
  1626.  if (x < 0) return(1-y);
  1627.  return(y);
  1628. }
  1629. /* derivata di sigma                        */
  1630.  
  1631. float dsig(float x)
  1632. {
  1633.  /* derivata della sigmoide -100..100 in funz. dello stato (output) */
  1634. static float tdsig[] =
  1635. {
  1636. .00,.01,.02,.03,.04,.05,.06,.07,.08,.09,.09,.10,.11,.12,.13,.14,.15,.16,.16,.17,
  1637. .18,.19,.20,.20,.21,.22,.23,.23,.24,.25,.25,.26,.27,.28,.28,.29,.30,.30,.31,.31,
  1638. .32,.33,.33,.34,.34,.35,.35,.36,.36,.37,.37,.38,.38,.39,.39,.40,.40,.41,.41,.42,
  1639. .42,.42,.43,.43,.44,.44,.44,.45,.45,.45,.45,.46,.46,.46,.47,.47,.47,.47,.48,.48,
  1640. .48,.48,.48,.49,.49,.49,.49,.49,.49,.49,.49,.50,.50,.50,.50,.50,.50,.50,.50,.50,
  1641. .50,
  1642. .50,.50,.50,.50,.50,.50,.50,.50,.50,.49,.49,.49,.49,.49,.49,.49,.49,.48,.48,.48,
  1643. .48,.48,.47,.47,.47,.47,.46,.46,.46,.45,.45,.45,.45,.44,.44,.44,.43,.43,.42,.42,
  1644. .42,.41,.41,.40,.40,.39,.39,.38,.38,.37,.37,.36,.36,.35,.35,.34,.34,.33,.33,.32,
  1645. .31,.31,.30,.30,.29,.28,.28,.27,.26,.25,.25,.24,.23,.23,.22,.21,.20,.20,.19,.18,
  1646. .17,.16,.16,.15,.14,.13,.12,.11,.10,.10,.09,.08,.07,.06,.05,.04,.03,.02,.01,.00,
  1647. };
  1648.  return((float) tdsig[(int) ((x+1)*100)]);
  1649. }
  1650.  
  1651. /* derivata di sigma2                       */
  1652.  
  1653. float dsig2(float x)
  1654. {
  1655.  /* derivata della sigmoide 0..100 in funzione dello stato (output) */
  1656. static float tdsig2[] =
  1657. {
  1658. .00,.01,.02,.03,.04,.05,.06,.07,.07,.08,.09,.10,.11,.11,.12,.13,.13,.14,.15,.15,
  1659. .16,.17,.17,.18,.18,.19,.19,.20,.20,.21,.21,.21,.22,.22,.22,.23,.23,.23,.24,.24,
  1660. .24,.24,.24,.25,.25,.25,.25,.25,.25,.25,
  1661. .25,
  1662. .25,.25,.25,.25,.25,.25,.25,.24,.24,.24,
  1663. .24,.24,.23,.23,.23,.22,.22,.22,.21,.21,.21,.20,.20,.19,.19,.18,.18,.17,.17,.16,
  1664. .15,.15,.14,.13,.13,.12,.11,.11,.10,.09,.08,.07,.07,.06,.05,.04,.03,.02,.01,.00,
  1665. };
  1666.  return((float) tdsig2[(int)(x*100)]);
  1667. }
  1668.  
  1669. /**************** carica le funzioni in tabella **************************/
  1670. struct tipofun
  1671. {
  1672.   char  *nomefun;
  1673.   int   far (*fun)();
  1674. }
  1675. listafun[] =
  1676. { {"f1",f1},
  1677.   {"f2",f2},
  1678.   {"f3",f3},
  1679.   {"f4",f4},
  1680.   {"f5",f5},
  1681.   {"f6",f6},
  1682.   {"f7",f7},
  1683.   {"f8",f8},
  1684.   {"f9",f9},
  1685.   {"f10",f10},
  1686.   {"f13",f13},
  1687.   {"f15",f15},
  1688.   {"a1",a1},
  1689.   {"a2",a2},
  1690.   {"a3",a3},
  1691.   {"a4",a4},
  1692.   {"a5",a5},
  1693.   {"a6",a6} };
  1694.  
  1695. #define NFUN (sizeof(listafun)/sizeof(struct tipofun))
  1696.  
  1697. void far *carfunz (char *tok)
  1698. {
  1699.   int i; int ret;
  1700.   for (i=0;i< NFUN;i++)
  1701.   {
  1702.     ret = strcmp(tok,listafun[i].nomefun);
  1703.     if (ret == 0) break;
  1704.   }
  1705.   if (i == NFUN) return(0);
  1706.   return(listafun[i].fun);
  1707. }
  1708.  
  1709. char *leggefunz (int far (*fun)())
  1710. {
  1711.   int i;
  1712.   for (i=0;i< NFUN;i++)
  1713.   {
  1714.     if (fun == listafun[i].fun) break;
  1715.   }
  1716.   if (i == NFUN) return("*");
  1717.   return(listafun[i].nomefun);
  1718. }
  1719.  
  1720. void fine()
  1721. {
  1722.  deallocamem();
  1723.  exit(-1);
  1724. }
  1725. /*-*/
  1726. /***************************************************************************/
  1727.  
  1728. /*****************************************************************************/
  1729. /*                        LIBRERIA DI GESTIONE                               */
  1730. /*****************************************************************************/
  1731.  
  1732. rmnet(int *maxr)
  1733. {
  1734.  *maxr = totr;
  1735.  return 0;
  1736. }
  1737.  
  1738. wmnet(int maxr)
  1739. {
  1740.  if (maxr > totr) return -1;
  1741.  totr= maxr;
  1742.  return 0;
  1743. }
  1744.  
  1745. totnn(int nr, LONG *tnodi)
  1746. {
  1747.  if (nr > totr) return -1;
  1748.  *tnodi = (r+nr)->d1;
  1749.  return 0;
  1750. }
  1751.  
  1752. rmlay(int nr,int *liv)
  1753. {
  1754.  if (nr > totr) return -1;
  1755.  *liv = (r+nr)->maxliv;
  1756.  return 0;
  1757. }
  1758.  
  1759. wmlay(int nr,int liv)
  1760. {
  1761.  if (nr > totr) return -1;
  1762.  if (liv > (r+nr)->maxliv) return -1;
  1763.  (r+nr)->maxliv = liv;
  1764.  return 0;
  1765. }
  1766.  
  1767. rlay(int nr,int nliv,LONG *sn,LONG *en)
  1768. {
  1769.  struct livello far *liv;
  1770.  if (nr > totr) return -1;
  1771.  if (nliv > (r+nr)->maxliv ) return -1;
  1772.  liv=(r+nr)->liv+nliv;
  1773.  *sn = liv->sn;
  1774.  *en = liv->en;
  1775.  return 0;
  1776. }
  1777.  
  1778. rstatl(int nr,int nliv,float stato[],int dim)
  1779. {
  1780.  struct livello far *liv;
  1781.  struct nodo    far *nodo;
  1782.  LONG nn;
  1783.  int i;
  1784.  nodo=(r+nr)->nodo;
  1785.  if (nr > totr) return -1;
  1786.  if (nliv > (r+nr)->maxliv ) return -1;
  1787.  liv=(r+nr)->liv+nliv;
  1788.  if (dim < liv->en - liv->sn + 1) return -1;
  1789.  i=1;
  1790.  for (nn= liv->sn; nn<= liv->en;nn++)
  1791.      {stato[i] = (*(nodo+nn)).stato;i++;}
  1792.  return i-1;
  1793. }
  1794.  
  1795. wstatl(int nr,int nliv,float stato[],int dim)
  1796. {
  1797.  struct livello far *liv;
  1798.  struct nodo    far *nodo;
  1799.  LONG nn;
  1800.  int i;
  1801.  nodo=(r+nr)->nodo;
  1802.  if (nr > totr) return -1;
  1803.  if (nliv > (r+nr)->maxliv ) return -1;
  1804.  liv=(r+nr)->liv+nliv;
  1805.  if (dim < liv->en - liv->sn + 1) return -1;
  1806.  i=1;
  1807.  for (nn= liv->sn; nn<= liv->en;nn++)
  1808.      {(*(nodo+nn)).stato = stato[i];i++;}
  1809.  return i-1;
  1810. }
  1811.  
  1812. rinpl(int nr,int nliv,float inp[],int dim)
  1813. {
  1814.  struct livello far *liv;
  1815.  struct nodo    far *nodo;
  1816.  LONG nn;
  1817.  int i;
  1818.  nodo=(r+nr)->nodo;
  1819.  if (nr > totr) return -1;
  1820.  if (nliv > (r+nr)->maxliv ) return -1;
  1821.  liv=(r+nr)->liv+nliv;
  1822.  if (dim < liv->en - liv->sn + 1) return -1;
  1823.  i=1;
  1824.  for (nn= liv->sn; nn<= liv->en;nn++)
  1825.      {inp[i] = (*(nodo+nn)).inp;i++;}
  1826.  return i-1;
  1827. }
  1828.  
  1829. winpl(int nr,int nliv,float inp[],int dim)
  1830. {
  1831.  struct livello far *liv;
  1832.  struct nodo    far *nodo;
  1833.  LONG nn;
  1834.  int i;
  1835.  nodo=(r+nr)->nodo;
  1836.  if (nr > totr) return -1;
  1837.  if (nliv > (r+nr)->maxliv ) return -1;
  1838.  liv=(r+nr)->liv+nliv;
  1839.  if (dim < liv->en - liv->sn + 1) return -1;
  1840.  i=1;
  1841.  for (nn= liv->sn; nn<= liv->en;nn++)
  1842.      {(*(nodo+nn)).inp = inp[i];i++;}
  1843.  return i-1;
  1844. }
  1845.  
  1846. rerrl(int nr,int nliv,float err[],int dim)
  1847. {
  1848.  return rinpl(nr, nliv, err, dim);
  1849. }
  1850.  
  1851. werrl(int nr,int nliv,float err[],int dim)
  1852. {
  1853.  return winpl(nr, nliv, err, dim);
  1854. }
  1855.  
  1856. rbiasl(int nr,int nliv,float bias[],int dim)
  1857. {
  1858.  struct livello far *liv;
  1859.  struct nodo    far *nodo;
  1860.  LONG nn;
  1861.  int i;
  1862.  nodo=(r+nr)->nodo;
  1863.  if (nr > totr) return -1;
  1864.  if (nliv > (r+nr)->maxliv ) return -1;
  1865.  liv=(r+nr)->liv+nliv;
  1866.  if (dim < liv->en - liv->sn + 1) return -1;
  1867.  i=1;
  1868.  for (nn= liv->sn; nn<= liv->en;nn++)
  1869.      {bias[i] = (*(nodo+nn)).bias;i++;}
  1870.  return i-1;
  1871. }
  1872.  
  1873. wbiasl(int nr,int nliv,float bias[],int dim)
  1874. {
  1875.  struct livello far *liv;
  1876.  struct nodo    far *nodo;
  1877.  LONG nn;
  1878.  int i;
  1879.  nodo=(r+nr)->nodo;
  1880.  if (nr > totr) return -1;
  1881.  if (nliv > (r+nr)->maxliv ) return -1;
  1882.  liv=(r+nr)->liv+nliv;
  1883.  if (dim < liv->en - liv->sn + 1) return -1;
  1884.  i=1;
  1885.  for (nn= liv->sn; nn<= liv->en;nn++)
  1886.      {(*(nodo+nn)).bias = bias[i];i++;}
  1887.  return i-1;
  1888. }
  1889.  
  1890. rwgtl(int nr,LONG nn,int nlivp,float peso[],int dim)
  1891. {
  1892.  struct livello far *liv;
  1893.  struct nodo    far *nodo;
  1894.  struct coll    far *collnn;
  1895.  LONG h,nh,sn,en,nnp;
  1896.  int i;
  1897.  nodo=(r+nr)->nodo;
  1898.  if (nr > totr) return -1;
  1899.  if (nn > (r+nr)->d1) return -1;
  1900.  if (nlivp > (r+nr)->maxliv ) return -1;
  1901.  liv=(r+nr)->liv+nlivp;
  1902.  sn = liv->sn; en = liv->en;
  1903.  collnn = (*(nodo+nn)).coll ;
  1904.  nh = (*(nodo+nn)).ncoll ;
  1905.  i=1;
  1906.  for (h= 0; h<= nh;h++)
  1907.    {
  1908.      nnp = (*(collnn+h)).nodo ;
  1909.      if( nnp >= sn && nnp <= en)
  1910.        {if (i > dim) return -1; else {peso[i] = (*(collnn+h)).peso ;i++;}}
  1911.    }
  1912.  return i-1;
  1913. }
  1914.  
  1915. wwgtl(int nr,LONG nn,int nlivp,float peso[],int dim)
  1916. {
  1917.  struct livello far *liv;
  1918.  struct nodo    far *nodo;
  1919.  struct coll    far *collnn;
  1920.  LONG h,nh,sn,en,nnp;
  1921.  int i;
  1922.  nodo=(r+nr)->nodo;
  1923.  if (nr > totr) return -1;
  1924.  if (nn > (r+nr)->d1) return -1;
  1925.  if (nlivp > (r+nr)->maxliv ) return -1;
  1926.  liv=(r+nr)->liv+nlivp;
  1927.  sn = liv->sn; en = liv->en;
  1928.  collnn = (*(nodo+nn)).coll ;
  1929.  nh = (*(nodo+nn)).ncoll ;
  1930.  i=1;
  1931.  for (h= 0; h<= nh;h++)
  1932.    {
  1933.      nnp = (*(collnn+h)).nodo ;
  1934.      if( nnp >= sn && nnp <= en)
  1935.        {if (i > dim) return -1; else { (*(collnn+h)).peso = peso[i];i++;}}
  1936.    }
  1937.  return i-1;
  1938. }
  1939.  
  1940. rwgtil(int nr,LONG npp,int nliva,float peso[],int dim)
  1941. {
  1942.  struct livello far *liv;
  1943.  struct nodo    far *nodo;
  1944.  struct coll    far *collnn;
  1945.  LONG h,nh,sn,en,nnp,nn;
  1946.  int i;
  1947.  nodo=(r+nr)->nodo;
  1948.  if (nr > totr) return -1;
  1949.  if (nn > (r+nr)->d1) return -1;
  1950.  if (nliva > (r+nr)->maxliv ) return -1;
  1951.  liv=(r+nr)->liv+nliva;
  1952.  sn = liv->sn; en = liv->en;
  1953.  i=1;
  1954.  for (nn=sn;nn<=en;nn++)
  1955.  {
  1956.    collnn = (*(nodo+nn)).coll ;
  1957.    nh = (*(nodo+nn)).ncoll ;
  1958.    for (h= 0; h<= nh;h++)
  1959.    {
  1960.      nnp = (*(collnn+h)).nodo ;
  1961.      if( nnp == npp)
  1962.        {if (i > dim) return -1; else {peso[i] = (*(collnn+h)).peso ;i++;}}
  1963.    }
  1964.  }
  1965.  return i-1;
  1966. }
  1967.  
  1968. wpesoil(int nr,LONG npp,int nliva,float peso[],int dim)
  1969. {
  1970.  struct livello far *liv;
  1971.  struct nodo    far *nodo;
  1972.  struct coll    far *collnn;
  1973.  LONG h,nh,sn,en,nnp,nn;
  1974.  int i;
  1975.  nodo=(r+nr)->nodo;
  1976.  if (nr > totr) return -1;
  1977.  if (nn > (r+nr)->d1) return -1;
  1978.  if (nliva > (r+nr)->maxliv ) return -1;
  1979.  liv=(r+nr)->liv+nliva;
  1980.  sn = liv->sn; en = liv->en;
  1981.  i=1;
  1982.  for (nn=sn;nn<=en;nn++)
  1983.  {
  1984.    collnn = (*(nodo+nn)).coll ;
  1985.    nh = (*(nodo+nn)).ncoll ;
  1986.    for (h= 0; h<= nh;h++)
  1987.    {
  1988.      nnp = (*(collnn+h)).nodo ;
  1989.      if( nnp == npp)
  1990.        {if (i > dim) return -1; else {(*(collnn+h)).peso = peso[i];i++;}}
  1991.    }
  1992.  }
  1993.  return i-1;
  1994. }
  1995.  
  1996. rstat(int nr,LONG nn,float *stato)
  1997. {
  1998.  struct nodo    far *nodo;
  1999.  nodo=(r+nr)->nodo;
  2000.  if (nr > totr) return -1;
  2001.  if (nn > (r+nr)->d1) return -1;
  2002.  *stato = (*(nodo+nn)).stato;
  2003.  return 0;
  2004. }
  2005.  
  2006. rbias(int nr,LONG nn,float *sog)
  2007. {
  2008.  struct nodo    far *nodo;
  2009.  nodo=(r+nr)->nodo;
  2010.  if (nr > totr) return -1;
  2011.  if (nn > (r+nr)->d1) return -1;
  2012.  *sog= (*(nodo+nn)).bias;
  2013.  return 0;
  2014. }
  2015.  
  2016. rinp(int nr,LONG nn,float *inp)
  2017. {
  2018.  struct nodo    far *nodo;
  2019.  nodo=(r+nr)->nodo;
  2020.  if (nr > totr) return -1;
  2021.  if (nn > (r+nr)->d1) return -1;
  2022.  *inp= (*(nodo+nn)).inp;
  2023.  return 0;
  2024. }
  2025.  
  2026. rerr(int nr,LONG nn,float *err)
  2027. {
  2028.   return rinp(nr,nn,err);
  2029. }
  2030.  
  2031.  
  2032. rfun(int nr,LONG nn,char fun[],char az[])
  2033. {
  2034.  struct nodo    far *nodo;
  2035.  nodo=(r+nr)->nodo;
  2036.  if (nr > totr) return -1;
  2037.  if (nn > (r+nr)->d1) return -1;
  2038.  strncpy(fun,leggefunz((*(nodo+nn)).funz),10);
  2039.  strncpy(az,leggefunz((*(nodo+nn)).azione),10);
  2040.  return 0;
  2041. }
  2042.  
  2043. wfun(int nr,LONG nn,char fun[],char az[])
  2044. {
  2045.  struct nodo    far *nodo;
  2046.  nodo=(r+nr)->nodo;
  2047.  if (nr > totr) return -1;
  2048.  if (nn > (r+nr)->d1) return -1;
  2049.  (*(nodo+nn)).funz=carfunz(fun);
  2050.  (*(nodo+nn)).azione=carfunz(az);
  2051.  return 0;
  2052. }
  2053.  
  2054. wstat(int nr,LONG nn,float stato)
  2055. {
  2056.  struct nodo    far *nodo;
  2057.  nodo=(r+nr)->nodo;
  2058.  if (nr > totr) return -1;
  2059.  if (nn > (r+nr)->d1) return -1;
  2060.  (*(nodo+nn)).stato = stato;
  2061.  return 0;
  2062. }
  2063.  
  2064. wbias(int nr,LONG nn,float bias)
  2065. {
  2066.  struct nodo    far *nodo;
  2067.  nodo=(r+nr)->nodo;
  2068.  if (nr > totr) return -1;
  2069.  if (nn > (r+nr)->d1) return -1;
  2070.  (*(nodo+nn)).bias = bias;
  2071.  return 0;
  2072. }
  2073.  
  2074. winp(int nr,LONG nn,float inp)
  2075. {
  2076.  struct nodo    far *nodo;
  2077.  nodo=(r+nr)->nodo;
  2078.  if (nr > totr) return -1;
  2079.  if (nn > (r+nr)->d1) return -1;
  2080.  (*(nodo+nn)).inp = inp;
  2081.  return 0;
  2082. }
  2083.  
  2084. werr(int nr,LONG nn,float err)
  2085. {
  2086.  return winp(nr,nn,err);
  2087. }
  2088.  
  2089.  
  2090. rnconn(int nr,LONG nn,LONG *ncoll)
  2091. {
  2092.  struct nodo    far *nodo;
  2093.  nodo=(r+nr)->nodo;
  2094.  if (nr > totr) return -1;
  2095.  if (nn > (r+nr)->d1) return -1;
  2096.  *ncoll= (*(nodo+nn)).ncoll;
  2097.  return 0;
  2098. }
  2099.  
  2100. rconn(int nr,LONG nn,LONG h,float *peso, LONG *ni)
  2101. {
  2102.  struct coll    far *collnn;
  2103.  struct nodo    far *nodo;
  2104.  nodo=(r+nr)->nodo;
  2105.  if (nr > totr) return -1;
  2106.  if (nn > (r+nr)->d1) return -1;
  2107.  collnn = (*(nodo+nn)).coll ;
  2108.  *peso  = (*(collnn+h)).peso ;
  2109.  *ni    = (*(collnn+h)).peso ;
  2110.  return 0;
  2111. }
  2112.  
  2113. wwgt(int nr,LONG nn,LONG h,float np)
  2114. {
  2115.  struct nodo    far *nodo;
  2116.  nodo=(r+nr)->nodo;
  2117.  if (nr > totr) return -1;
  2118.  if (nn > (r+nr)->d1) return -1;
  2119.  if (h > (*(nodo+nn)).ncoll) return -1;
  2120.  (*((*(nodo+nn)).coll+h)).peso = np;
  2121.  return 0;
  2122. }
  2123.  
  2124. wnodp(int nr,LONG nn,LONG h,LONG ni)
  2125. {
  2126.  struct nodo    far *nodo;
  2127.  nodo=(r+nr)->nodo;
  2128.  if (nr > totr) return -1;
  2129.  if (nn > (r+nr)->d1) return -1;
  2130.  if (h > (*(nodo+nn)).ncoll) return -1;
  2131.  (*((*(nodo+nn)).coll+h)).nodo = ni;
  2132.  return 0;
  2133. }
  2134. wnconn(int nr,LONG nn,LONG ncoll)
  2135. {
  2136.  struct nodo    far *nodo;
  2137.  nodo=(r+nr)->nodo;
  2138.  if (nr > totr) return -1;
  2139.  if (nn > (r+nr)->d1) return -1;
  2140.  if (ncoll > (*(nodo+nn)).ncoll) return -1;
  2141.  (*(nodo+nn)).ncoll = ncoll;
  2142.  return 0;
  2143. }
  2144. /*****************************************************************************/
  2145.  
  2146.  
  2147. /*****************************************************************************/
  2148. /*                          MESSAGGI DI ERRORE                               */
  2149. /*****************************************************************************/
  2150. void errmess (int cod)
  2151. {
  2152.  switch(cod)
  2153.   {
  2154.    case NOMEM   : printf("Can't allocate memory \r\n");break;
  2155.    case NOFILEI : printf("Can't open file %s \r\n",fileinp);break;
  2156.    case NOFILEO : printf("Can't open file %s \r\n",fileout);break;
  2157.    case NODIM   : printf("Error in dimensions or no dimensions \r\n");break;
  2158.    case NONODO  : printf("Error or no values for node \r\n");break;
  2159.    case TOOCOLL : printf("Too connections (> total connections) \r\n");break;
  2160.    case NOLIV   : printf("Error or no layer's number \r\n");break;
  2161.    case TOOLIV  : printf("Layer's number  > 99 \r\n");break;
  2162.    case NOMEMV  : printf("Insufficient memory for arrays inp, out, dat \r\n");break;
  2163.    case NOFILEES: printf("Can't open file %s \r\n",fileese);break;
  2164.    case ERRESE  : printf("Error in training file  \r\n");break;
  2165.    case NOTRETE : printf("No total nets \r\n");break;
  2166.    case NOTLIV  : printf("No total layers \r\n");break;
  2167.    case NONUMR  : printf("No net number \r\n");break;
  2168.    case TOONET  : printf("Too nets ( > 1000) \r\n");break;
  2169.    case NOSTRUCT: printf("Don't still exist structure for nets descr. \r\n");break;
  2170.    case CREARETE: printf("Don't still exist net  \r\n");break;
  2171.   }
  2172. }
  2173. /*****************************************************************************/
  2174.  
  2175.